package nl.haemers.collections 
{
	import nl.haemers.collections.interfaces.IIterator;
	import nl.haemers.collections.interfaces.IList;
	
	import nl.haemers.collections.errors.NoSuchElementException;
	import nl.haemers.collections.errors.ConcurrentModificationException;
	
	import nl.haemers.utils.Logger;
	/**
	 * @author Jonathan Haemers
	 * Iterator used only by AbstractList
	 */
	//TODO: check if we could implement modcount
	public class Iterator implements IIterator
	{		
		protected var cursor					:int = 0;
		protected var _expectedModCount			:int;
		protected var lastRet					:int = -1;
		
		protected var _list						:IList;
		protected var node						:LinkedNode;
		
		public function Iterator(expectedModCount:int, list:IList) 
		{
			_expectedModCount = expectedModCount;
			_list = list;
		}
		
		/** Public methods **/
		
		/** Getters & Setters **/
		public function get expectedModCount() : int
		{ 
			return _expectedModCount;
		}
		public function set expectedModCount( value:int ) : void 
		{
			_expectedModCount = value;
		}
		
		public function hasNext() : Boolean
		{
            return cursor+1 < _list.size;
        }
		
		
        public function next() : Object 
		{
			/*
			 * it requires some extra lines of code but for iteration calling less methods is 
			 * just faster.
			 */
			/*
            if (_expectedModCount == modCount) 
			{
			*/
			//Way too slow
				try 
				{
					var result:Object = _list.get(cursor);
					lastRet = cursor++;
					return result;
				} 
				catch (e:RangeError) 
				{
					throw new NoSuchElementException();
				}
            /*
			}
            throw new ConcurrentModificationException();
			*/
			return null;
        }
		
		public function remove() : void
		{
			/*
			if (expectedModCount == modCount) 
			{
			*/
				try 
				{
					_list.removeAt(lastRet);
				}
				catch (e:RangeError) 
				{
					//I dont think this will ever happen...
					//throw new IllegalStateException();
					Logger.w("throw new IllegalStateException()", this);
				}
				/*
				if (modCount != expectedModCount) 
				{
					expectedModCount++;
				}
				*/
				expectedModCount++;
				
				if (lastRet < cursor) 
				{
					cursor--;
				}
			
				lastRet = -1;
			/*	
            }
			else 
			{
				throw new ConcurrentModificationException();
            }
			*/
		}
	}
}